package com.baidu.mpks.filter;


import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.Collection;

@Component
public class LoginMaxOnlineAccountFilter extends AccessControlFilter implements InitializingBean {
    private static final Logger log = LoggerFactory.getLogger(LoginMaxOnlineAccountFilter.class);
    private SessionDAO sessionDAO;
    @Value("${login.max.all.session:20000}")
    private int maxOnlineAccountNum;

    public LoginMaxOnlineAccountFilter() {
    }

    @Autowired
    public void setSessionDAO(SessionDAO sessionDAO) {
        this.sessionDAO = sessionDAO;
    }

    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        return false;
    }

    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        Subject subject = this.getSubject(request, response);
        Collection<Session> sessions = this.sessionDAO.getActiveSessions();
        if (sessions.size() > this.maxOnlineAccountNum) {
            try {
                subject.logout();
            } catch (Exception var6) {
                log.warn("logout error {}", var6.getMessage(), var6);
            }

            HttpServletResponse resp = (HttpServletResponse)response;
            resp.setStatus(401);
            resp.setHeader("login_error_msg", URLEncoder.encode("超过了最大链接数", "UTF-8"));
            return false;
        } else {
            return true;
        }
    }

    public void afterPropertiesSet() {
        Factory<SecurityManager> factory = new IniSecurityManagerFactory();
        SecurityManager securityManager = (SecurityManager)factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
    }
}
